package com.three.mahjong.base.service;

import com.three.mahjong.base.model.*;
import com.three.mahjong.base.rule.MJBaseRule;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * 玩家是否能操作列表
 */
@Component
public class JudgeMethod {

    @Autowired
    private MJBaseRule mjBaseRule;

    /**
     * 判断玩家牌型是否为混一色
     *
     * @param allPaiList
     *            已经整合到一起的玩家全部牌(手牌，碰杠牌)
     * @return
     */
    public boolean isHunYiSe(List<Card> allPaiList) {
        boolean flag = false;

        int[][] allPaiArray = mjBaseRule.convertTwoArrays(allPaiList);

        if (allPaiArray[3][0] > 0 && allPaiArray.length == 2) {
            flag = true;
        }

        return flag;
    }


    /**
     * 分析每一种牌是否符合
     *
     * @param aKindPai
     * @return
     */
    public boolean analyze(int[] aKindPai) {

        if (aKindPai[0] == 0) {
            return true;
        }
        int index = 0;
        for (int i = 1; i <= 9; i++) {
            if (aKindPai[i] != 0) {
                index = i;
                break;
            }
        }
        boolean result = false;
        if (aKindPai[index] >= 3) {
            aKindPai[index] = aKindPai[index] - 3;
            aKindPai[0] = aKindPai[0] - 3;
            result = analyze(aKindPai);
            aKindPai[index] = aKindPai[index] + 3;
            aKindPai[0] = aKindPai[0] + 3;
            return result;
        }

        //TODO 改动  先删除 !ziPai 的判断
        if (index < 8 && aKindPai[index + 1] > 0 && aKindPai[index + 2] > 0) {
            aKindPai[index] = aKindPai[index] - 1;
            aKindPai[index + 1] = aKindPai[index + 1] - 1;
            aKindPai[index + 2] = aKindPai[index + 2] - 1;
            aKindPai[0] = aKindPai[0] - 3;
            result = analyze(aKindPai);
            aKindPai[index] = aKindPai[index] + 1;
            aKindPai[index + 1] = aKindPai[index + 1] + 1;
            aKindPai[index + 2] = aKindPai[index + 2] + 1;
            aKindPai[0] = aKindPai[0] + 3;
            return result;
        }
        return false;
    }

    /**
     * 胡手牌
     *
     * @param allPai
     * @return
     */
    public boolean isHuPai(int[][] allPai) {

        int jiangPos = 0;// 将对
        int yuShu = 0;
        boolean jiangExisted = false;
        for (int i = 0; i < 4; i++) {
            yuShu = allPai[i][0] % 3;
            if (yuShu == 1) {
                return false;
            }
            if (yuShu == 2) {
                if (jiangExisted) {
                    return false;
                }
                jiangPos = i;
                jiangExisted = true;
            }
        }

        for (int i = 0; i < 4; i++) {
            if (i != jiangPos) {
                int[] temp = new int[10];
                for (int j = 0; j <= 9; j++) {
                    temp[j] = allPai[i][j];
                }
                if (!analyze(temp)) {
                    return false;
                }
            }
        }

        boolean success = false;

        for (int j = 1; j <= 9; j++) {
            if (allPai[jiangPos][j] >= 2) {
                allPai[jiangPos][j] = allPai[jiangPos][j] - 2;
                allPai[jiangPos][0] = allPai[jiangPos][0] - 2;

                int[] temp = new int[10];
                for (int k = 0; k <= 9; k++) {
                    temp[k] = allPai[jiangPos][k];
                }
                if (analyze(temp)) {
                    success = true;
                }
                allPai[jiangPos][j] = allPai[jiangPos][j] + 2;
                allPai[jiangPos][0] = allPai[jiangPos][0] + 2;
                if (success) {
                    break;
                }
            }
        }
        return success;
    }


    /**
     * 判断玩家是否能胡
     *
     * @param handPaiList
     * @return
     */
    public boolean isHu(List<Card> handPaiList) {
        boolean flag = false;

        // 普通胡
        int[][] shouPai = mjBaseRule.convertTwoArrays(handPaiList);

        if (isHuPai(shouPai)) {
            flag = true;
        }

        return flag;
    }

    /**
     * 判断玩家能否吃牌
     *
     * @param pai
     *            需要吃进来的牌
     * @param mahjongPlayer
     *            玩家对象
     * @param mahjongTable 牌桌对象
     * @return
     */
    public boolean canChi(Integer pai, MJPlayer mahjongPlayer, MJTable mahjongTable) {
        boolean flag = false;
        //获取牌桌打出这张牌的玩家座位
        int lastSeat = mahjongTable.getLastSeat();
        //计算下一个玩家座位
        int nextSeat = mjBaseRule.getNextSeat(lastSeat);
        if(nextSeat != mahjongPlayer.getSeat()){
            return flag;
        }
        List<Card> handPaiList = mjBaseRule.changeToCardList(mahjongPlayer.getHandPaiList());
        Map<Integer, List<Card>> chiPaiList = mjBaseRule.calculateChiPaiInfo(pai, handPaiList);
        if (!chiPaiList.isEmpty()) {
            flag = true;
        }

        return flag;
    }

    /**
     * 胡牌
     * 龙七对可以看做巧七对的一种
     * @param allPai
     * @return
     */
    public boolean duiduiHu(int[][] allPai) {
        // 对对胡
        boolean isDuizi = true;
        for (int i = 0; i < 4; i++) {
            for (int j = 1; j <= 9; j++) {
                if (allPai[i][j] > 0 && (allPai[i][j] != 2 && allPai[i][j] != 4)) {//4为龙7对的判定
                    isDuizi = false;
                    break;
                }
            }
            if (!isDuizi) {
                break;
            }
        }
        if (isDuizi) {
            return true;
        }
        return false;
    }


    /**
     * 胡加七小对
     * @param memberPai 玩家手牌
     * @param showPais 碰杠牌
     * @return
     */
    public boolean fitHu(int[][] memberPai, List<ShowPai> showPais){
        boolean huPai=false;
        if (isHuPai(memberPai)) {
            huPai = true;
        } else {
            if (showPais.isEmpty()) {
                if (duiduiHu(memberPai)){
                    huPai = true;
                }
            }
        }
        return huPai;
    }




    /**
     * 判断玩家是否能碰
     *
     * @param pai 目标牌
     * @param handPaiList 玩家手牌
     * @return
     */
    public boolean canPeng(Integer pai, List<Card> handPaiList) {
        boolean flag = false;
        // 获取牌类型
        int paiType = mjBaseRule.getPaiType(pai);
        // 获取牌下标
        int paiIndex = (pai % 100) / 10;

        int[][] paiArray = mjBaseRule.convertTwoArrays(handPaiList);
        // 获取玩家手牌列表中目标牌的数量
        int paiNum = paiArray[paiType-1][paiIndex];

        if (paiNum >= 2) {
            flag = true;
        }

        return flag;
    }

    /**
     * 判断玩家是否能杠牌
     * @param targetPai 目标牌
     * @param handPaiList 玩家手牌
     * @return
     */
    public boolean canGang(Integer targetPai,List<Card> handPaiList){
        boolean flag = false;

        if(handPaiList.isEmpty()){
            return flag;
        }

        // 获取牌类型
        int paiType = mjBaseRule.getPaiType(targetPai);
        // 获取牌下标
        int paiIndex = (targetPai % 100) / 10;

        int[][] paiArray = mjBaseRule.convertTwoArrays(handPaiList);
        // 获取玩家手牌列表中目标牌的数量
        int paiNum = paiArray[paiType-1][paiIndex];

        if (paiNum == 3) {
            flag = true;
        }

        return flag;
    }



    public boolean isGangShangPao(MJPlayer mahjongPlayer){
        boolean flag = false;
        //TODO 杠上炮
        return flag;
    }


    public boolean isGangShangKaiHua(){
        boolean flag = false;
        //TODO 杠上开花
        return flag;
    }







}
